package org.xxx.epms.gateway.security.component;

import cn.hutool.core.text.AntPathMatcher;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.security.authentication.ReactiveAuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.security.web.server.context.ServerSecurityContextRepository;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.xxx.epms.common.utils.JwtTokenUtil;
import org.xxx.epms.gateway.config.service.AdminDetailsService;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * JwtSecurityContextRepository
 * Description: Jwt授权信息存储
 *
 * @author lb
 */

@Component
@Slf4j
public class JwtSecurityContextRepository implements ServerSecurityContextRepository {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    private final String TOKEN_HEADER = "Authorization";
    private final String TOKEN_HEAD = "Bearer ";

    @Autowired
    private AdminDetailsService adminDetailsService;

    private Map<String, UserDetailsService> userDetailsServiceMap;
    private void initUserDetailsServiceMap(){
        userDetailsServiceMap = new HashMap<String,UserDetailsService>();
        userDetailsServiceMap.put("adm",this.adminDetailsService);
    }

    @Override
    public Mono<Void> save(ServerWebExchange exchange, SecurityContext context) {
        return Mono.empty();
    }

    @Override
    public Mono<SecurityContext> load(ServerWebExchange exchange) {
//        ServerHttpRequest request = exchange.getRequest();
//        AntPathMatcher antPathMatcher = new AntPathMatcher();
//
//        if(antPathMatcher.match("/admin/login", request.getURI().getPath())){
//            return Mono.empty();
//        }
//
//        initUserDetailsServiceMap();
//        String authHeader = request.getHeaders().getFirst(TOKEN_HEADER);
//        String token = authHeader.substring(TOKEN_HEAD.length());
//        String username = jwtTokenUtil.getUserNameFromToken(token);
//        String userType = jwtTokenUtil.getUserTypeFromToken(token);
//
//        UserDetails userDetails = this.userDetailsServiceMap.get(userType).loadUserByUsername(username);
//        if (jwtTokenUtil.validateToken(token, userDetails)) {
//            return new ReactiveAuthenticationManager() {
//                @Override
//                public Mono<Authentication> authenticate(Authentication authentication) {
//                    return Mono.fromCallable(() -> {
//                        UsernamePasswordAuthenticationToken adminAuthentication =
//                                new UsernamePasswordAuthenticationToken(
//                                        userDetails, null, userDetails.getAuthorities());
//                        System.out.println(adminAuthentication.getAuthorities());
//                        log.info("authenticated user:{}", username);
//                        return adminAuthentication;
//                    });
//                }
//            }.authenticate(null).map(SecurityContextImpl::new);
//        }
        return Mono.empty();
    }
}
